package com.yy.finvideoplayer.renderview

import android.view.View
import java.lang.ref.WeakReference
import kotlin.math.min

/**
 * 根据缩放模式设置渲染view的大小
 * @Description: MeasureHelper
 * @Author: yiw89
 * @CreateDate: 2025/9/1 14:52
 * @Version: 1.0
 */
class MeasureHelper(view: View) {
    private val mWeakView: WeakReference<View>? = WeakReference(view)

    private var mVideoWidth = 0
    private var mVideoHeight = 0
    private var mVideoSarNum = 0
    private var mVideoSarDen = 0

    private var mVideoRotationDegree = 0

    private var mMeasuredWidth = 0
    private var mMeasuredHeight = 0

    private var mCurrentAspectRatio: Int =
        IRenderView.AR_ASPECT_FIT_PARENT

    fun getView(): View? {
        if (mWeakView == null) return null
        return mWeakView.get()
    }

    fun setVideoSize(videoWidth: Int, videoHeight: Int) {
        mVideoWidth = videoWidth
        mVideoHeight = videoHeight
    }

    fun setVideoSampleAspectRatio(videoSarNum: Int, videoSarDen: Int) {
        mVideoSarNum = videoSarNum
        mVideoSarDen = videoSarDen
    }

    fun setVideoRotation(videoRotationDegree: Int) {
        mVideoRotationDegree = videoRotationDegree
    }

    /**
     * 根据模式计算视频显示的大小
     */
    fun doMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        var widthMeasureSpec = widthMeasureSpec
        var heightMeasureSpec = heightMeasureSpec
        if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
            val tempSpec = widthMeasureSpec
            widthMeasureSpec = heightMeasureSpec
            heightMeasureSpec = tempSpec
        }

        var width = View.getDefaultSize(mVideoWidth, widthMeasureSpec)
        var height = View.getDefaultSize(mVideoHeight, heightMeasureSpec)
        if (mCurrentAspectRatio == IRenderView.AR_MATCH_PARENT) {
            width = widthMeasureSpec
            height = heightMeasureSpec
        } else if (mVideoWidth > 0 && mVideoHeight > 0) {
            val widthSpecSize = width
            val heightSpecSize = height

            //Log.i("viewsize", "容器控件大小 = " + widthSpecSize + "," + heightSpecSize);
            var displayAspectRatio: Float //计算不同模式的视频比例
            when (mCurrentAspectRatio) {
                IRenderView.AR_16_9_FIT_PARENT -> {
                    displayAspectRatio = 16.0f / 9.0f
                    if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) displayAspectRatio =
                        1.0f / displayAspectRatio
                }

                IRenderView.AR_4_3_FIT_PARENT -> {
                    displayAspectRatio = 4.0f / 3.0f
                    if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) displayAspectRatio =
                        1.0f / displayAspectRatio
                }

                IRenderView.AR_ASPECT_FIT_PARENT, IRenderView.AR_ASPECT_FILL_PARENT, IRenderView.AR_ASPECT_WRAP_CONTENT -> {
                    displayAspectRatio = mVideoWidth.toFloat() / mVideoHeight.toFloat()
                    if (mVideoSarNum > 0 && mVideoSarDen > 0) displayAspectRatio =
                        displayAspectRatio * mVideoSarNum / mVideoSarDen
                }

                else -> {
                    displayAspectRatio = mVideoWidth.toFloat() / mVideoHeight.toFloat()
                    if (mVideoSarNum > 0 && mVideoSarDen > 0) displayAspectRatio =
                        displayAspectRatio * mVideoSarNum / mVideoSarDen
                }
            }
            //容器view比例
            val specAspectRatio = widthSpecSize.toFloat() / heightSpecSize.toFloat()
            //容器比例和视频比例大小 (确定是哪一边抵触边缘用,true表示视频比容器胖 false表示表示比较瘦
            val shouldBeWider = displayAspectRatio > specAspectRatio
            when (mCurrentAspectRatio) {
                IRenderView.AR_ASPECT_FILL_PARENT -> if (shouldBeWider) {
                    // not high enough, fix height
                    height = heightSpecSize
                    width = (height * displayAspectRatio).toInt()
                } else {
                    // not wide enough, fix width
                    width = widthSpecSize
                    height = (width / displayAspectRatio).toInt()
                }

                IRenderView.AR_ASPECT_WRAP_CONTENT -> if (shouldBeWider) {
                    // too wide, fix width
                    width = min(mVideoWidth.toDouble(), widthSpecSize.toDouble()).toInt()
                    height = (width / displayAspectRatio).toInt()
                } else {
                    // too high, fix height
                    height = min(mVideoHeight.toDouble(), heightSpecSize.toDouble()).toInt()
                    width = (height * displayAspectRatio).toInt()
                }

                IRenderView.AR_ASPECT_FIT_PARENT, IRenderView.AR_16_9_FIT_PARENT, IRenderView.AR_4_3_FIT_PARENT -> if (shouldBeWider) {
                    // too wide, fix width
                    width = widthSpecSize
                    height = (width / displayAspectRatio).toInt()
                } else {
                    // too high, fix height
                    height = heightSpecSize
                    width = (height * displayAspectRatio).toInt()
                }

                else -> if (shouldBeWider) {
                    width = widthSpecSize
                    height = (width / displayAspectRatio).toInt()
                } else {
                    height = heightSpecSize
                    width = (height * displayAspectRatio).toInt()
                }
            }
        }

        mMeasuredWidth = width
        mMeasuredHeight = height

        //Log.i("viewsize", "视频大小 = " + mVideoWidth + "," + mVideoHeight
        //        + "\n改变后view大小 = " + width + "," + height);
    }

    fun getMeasuredWidth(): Int {
        return mMeasuredWidth
    }

    fun getMeasuredHeight(): Int {
        return mMeasuredHeight
    }

    fun setAspectRatio(aspectRatio: Int) {
        mCurrentAspectRatio = aspectRatio
    }
}